//
//  RefreshView.m
//  XinDong
//
//  Created by tt on 12-11-8.
//  Copyright (c) 2012年 HengYongKeJi. All rights reserved.
//

#import "RefreshView.h"

#define OffSet	50.f
#define WIDTH_PAGE	280.f		// 单页宽

@interface RefreshView (Private)

- (void)setState:(RefreshState)aState;

@end


@implementation RefreshView

@synthesize delegate=_delegate;

- (id)initWithFrame:(CGRect)frame position:(RefreshViewPosition)position{
    self = [super initWithFrame:frame];
    if (self) {
        CALayer *layer = [CALayer layer];
		layer.contentsGravity = kCAGravityResizeAspect;
		layer.contents = (id)[UIImage imageNamed:@"blackArrow.png"].CGImage;
        
		_position = position;
		switch (_position) {
			case RefreshViewTop:
				layer.transform = CATransform3DIdentity;
				layer.frame = CGRectMake(400.f, frame.size.height - 65.0f, 30.0f, 55.0f);
				break;
			case RefreshViewBottom:
				layer.transform = CATransform3DMakeRotation((M_PI / 180.0) * 180.0f, 0.0f, 0.0f, 1.0f);
				layer.frame = CGRectMake(OffSet, 20.0f, 23.0f, 60.0f);
				break;
			case RefreshViewLeft:
				layer.transform = CATransform3DMakeRotation((M_PI / 180.0) * 270.0f, 0.0f, 0.0f, 1.0f);
				layer.frame = CGRectMake(frame.size.width - 95.f, OffSet, 60.0f, 23.0f);
				break;
			case RefreshViewRight:
				layer.transform = CATransform3DMakeRotation((M_PI / 180.0) * 90.0f, 0.0f, 0.0f, 1.0f);
				layer.frame = CGRectMake(35.0f, OffSet, 60.0f, 23.0f);
				break;
		}
		
		if (_position == RefreshViewTop) {
			UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, frame.size.height - 30.0f, self.frame.size.width, 20.0f)];
			label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
			label.font = [UIFont systemFontOfSize:12.0f];
			label.textColor = [UIColor colorWithRed:87.0/255.0 green:108.0/255.0 blue:137.0/255.0 alpha:1.0];
			label.shadowColor = [UIColor colorWithWhite:0.9f alpha:1.0f];
			label.shadowOffset = CGSizeMake(0.0f, 1.0f);
			label.backgroundColor = [UIColor clearColor];
			label.textAlignment = UITextAlignmentCenter;
			[self addSubview:label];
			_lastUpdatedLabel=label;
			
			label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, frame.size.height - 48.0f, self.frame.size.width, 20.0f)];
			label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
			label.font = [UIFont boldSystemFontOfSize:13.0f];
			label.textColor = [UIColor colorWithRed:87.0/255.0 green:108.0/255.0 blue:137.0/255.0 alpha:1.0];
			label.shadowColor = [UIColor colorWithWhite:0.9f alpha:1.0f];
			label.shadowOffset = CGSizeMake(0.0f, 1.0f);
			label.backgroundColor = [UIColor clearColor];
			label.textAlignment = UITextAlignmentCenter;
			[self addSubview:label];
			_statusLabel=label;
		}
		
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
		if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
			layer.contentsScale = [[UIScreen mainScreen] scale];
		}
#endif
		[[self layer] addSublayer:layer];
		_arrowImage=layer;
		
		UIActivityIndicatorView *view = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
		view.center = CGPointMake(CGRectGetMidX(layer.frame), CGRectGetMidY(layer.frame));
		if (_position == RefreshViewTop) {
			view.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
			view.frame = CGRectMake(25.0f, frame.size.height - 38.0f, 20.0f, 20.0f);
		}
		[self addSubview:view];
		_activityView = view;
		
		[self setState:RefreshNormal];
    }
    return self;
}


#pragma mark -
#pragma mark Setters

- (void)refreshLastUpdatedDate {
	
	//if ([_delegate respondsToSelector:@selector(refreshTableHeaderDataSourceLastUpdated:)]) {
    
    NSDate *date = [_delegate refreshTableHeaderDataSourceLastUpdated:self];
	if(date == NULL){
        date = [NSDate date];
    }
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"MM/dd/yyyy HH:mm"];
    _lastUpdatedLabel.text = [NSString stringWithFormat:LocalizedString(@"Last updated: %@"), [formatter stringFromDate:date]];
}

- (void)setState:(RefreshState)aState {
	switch (aState) {
		case RefreshPulling:
			if (_position == RefreshViewTop) {
				_statusLabel.text = LocalizedString(@"Release to update...");
			}
			[CATransaction begin];
			[CATransaction setAnimationDuration:0.18f];
			switch (_position) {
				case RefreshViewTop:
					_arrowImage.transform = CATransform3DMakeRotation((M_PI / 180.0) * 180.0f, 0.0f, 0.0f, 1.0f);
					break;
				case RefreshViewBottom:
					_arrowImage.transform = CATransform3DIdentity;
					break;
				case RefreshViewLeft:
					_arrowImage.transform = CATransform3DMakeRotation((M_PI / 180.0) * 90.0f, 0.0f, 0.0f, 1.0f);
					break;
				case RefreshViewRight:
					_arrowImage.transform = CATransform3DMakeRotation((M_PI / 180.0) * 270.0f, 0.0f, 0.0f, 1.0f);
					break;
			}
			[CATransaction commit];
			break;
		case RefreshNormal:
			if (_position == RefreshViewTop) {
				_statusLabel.text = LocalizedString(@"Pull down to update...");
			}
			if (_state == RefreshPulling) {
				[CATransaction begin];
				[CATransaction setAnimationDuration:0.18f];
				switch (_position) {
					case RefreshViewTop:
						_arrowImage.transform = CATransform3DIdentity;
						break;
					case RefreshViewBottom:
						_arrowImage.transform = CATransform3DMakeRotation((M_PI / 180.0) * 180.0f, 0.0f, 0.0f, 1.0f);
						break;
					case RefreshViewLeft:
						_arrowImage.transform = CATransform3DMakeRotation((M_PI / 180.0) * 270.0f, 0.0f, 0.0f, 1.0f);
						break;
					case RefreshViewRight:
						_arrowImage.transform = CATransform3DMakeRotation((M_PI / 180.0) * 90.0f, 0.0f, 0.0f, 1.0f);
						break;
				}
				[CATransaction commit];
			}
			
			[_activityView stopAnimating];
			[CATransaction begin];
			[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
			_arrowImage.hidden = NO;
			switch (_position) {
				case RefreshViewTop:
					_arrowImage.transform = CATransform3DIdentity;
					break;
				case RefreshViewBottom:
					_arrowImage.transform = CATransform3DMakeRotation((M_PI / 180.0) * 180.0f, 0.0f, 0.0f, 1.0f);
					break;
				case RefreshViewLeft:
					_arrowImage.transform = CATransform3DMakeRotation((M_PI / 180.0) * 270.0f, 0.0f, 0.0f, 1.0f);
					break;
				case RefreshViewRight:
					_arrowImage.transform = CATransform3DMakeRotation((M_PI / 180.0) * 90.0f, 0.0f, 0.0f, 1.0f);
					break;
			}
			[CATransaction commit];
			[self refreshLastUpdatedDate];
			break;
		case RefreshLoading:
			if (_position == RefreshViewTop) {
				_statusLabel.text = LocalizedString(@"Loading...");
			}
			[_activityView startAnimating];
			[CATransaction begin];
			[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
			_arrowImage.hidden = YES;
			[CATransaction commit];
			break;
	}
	_state = aState;
}

- (void)setAutoPulling:(BOOL)autoPulling
{
    _autoPulling = autoPulling;
}

#pragma mark -
#pragma mark ScrollView Methods

- (void)refreshScrollViewDidScroll:(UIScrollView *)scrollView {
	
	if (_state == RefreshLoading) {
		CGFloat offset;
		switch (_position) {
			case RefreshViewTop:
				offset = MAX(scrollView.contentOffset.y * -1, 0);
				offset = MIN(offset, 60.f);
				scrollView.contentInset = UIEdgeInsetsMake(offset, 0.0f, 0.0f, 0.0f);
				break;
			case RefreshViewBottom:
				offset = MAX(scrollView.contentOffset.y * 1, 0);
				offset = MIN(offset, 60.f);
				scrollView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, offset, 0.0f);
				break;
			case RefreshViewLeft:
				offset = MAX(scrollView.contentOffset.x * -1, 0);
				offset = MIN(offset, 60.f);
				scrollView.contentInset = UIEdgeInsetsMake(0.0f, offset, 0.0f, 0.0f);
				break;
			case RefreshViewRight:
				offset = MAX(scrollView.contentOffset.x * 1, 0);
				offset = MIN(offset, 60.f);
				scrollView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, offset);
				break;
		}
	} else if (scrollView.isDragging || _autoPulling) {
		
		BOOL _loading = NO;
		if ([_delegate respondsToSelector:@selector(refreshDataSourceIsLoading:)]) {
			_loading = [_delegate refreshDataSourceIsLoading:self];
		}
		
		switch (_position) {
			case RefreshViewTop:
				if (_state == RefreshPulling && scrollView.contentOffset.y > -OffSet && scrollView.contentOffset.y < 0.0f && !_loading) {
					[self setState:RefreshNormal];
				} else if (_state == RefreshNormal && scrollView.contentOffset.y < -OffSet && !_loading) {
					[self setState:RefreshPulling];
				}
				if (scrollView.contentInset.top != 0) {
					scrollView.contentInset = UIEdgeInsetsZero;
				}
				break;
			case RefreshViewBottom:
				if (_state == RefreshPulling && scrollView.contentOffset.y < scrollView.contentSize.height - 480.f + OffSet && scrollView.contentOffset.y > scrollView.contentSize.height - 480.f && !_loading) {
					[self setState:RefreshNormal];
				} else if (_state == RefreshNormal && scrollView.contentOffset.y > scrollView.contentSize.height - 480.f + OffSet && !_loading) {
					[self setState:RefreshPulling];
				}
				if (scrollView.contentInset.bottom != 0) {
					scrollView.contentInset = UIEdgeInsetsZero;
				}
				break;
			case RefreshViewLeft:
				if (_state == RefreshPulling && scrollView.contentOffset.x > -OffSet && scrollView.contentOffset.x < 0.0f && !_loading) {
					[self setState:RefreshNormal];
				} else if (_state == RefreshNormal && scrollView.contentOffset.x < -OffSet && !_loading) {
					[self setState:RefreshPulling];
				}
				if (scrollView.contentInset.left != 0) {
					scrollView.contentInset = UIEdgeInsetsZero;
				}
				break;
			case RefreshViewRight:
				if (_state == RefreshPulling && scrollView.contentOffset.x < scrollView.contentSize.width - (WIDTH_PAGE + (320.f - WIDTH_PAGE) / 2.f) + OffSet && scrollView.contentOffset.x > scrollView.contentSize.width - (WIDTH_PAGE + (320.f - WIDTH_PAGE) / 2.f) && !_loading) {
					[self setState:RefreshNormal];
				} else if (_state == RefreshNormal && scrollView.contentOffset.x > scrollView.contentSize.width - (WIDTH_PAGE + (320.f - WIDTH_PAGE) / 2.f) + OffSet && !_loading) {
					[self setState:RefreshPulling];
				}
				if (scrollView.contentInset.right != 0) {
					scrollView.contentInset = UIEdgeInsetsZero;
				}
				break;
		}
	}
}

- (void)refreshScrollViewDidEndDragging:(UIScrollView *)scrollView {
	BOOL _loading = NO;
	if ([_delegate respondsToSelector:@selector(refreshDataSourceIsLoading:)]) {
		_loading = [_delegate refreshDataSourceIsLoading:self];
	}
	switch (_position) {
		case RefreshViewTop:
			if (scrollView.contentOffset.y <= - OffSet && !_loading) {
				
				if ([_delegate respondsToSelector:@selector(refreshDidTriggerRefresh:)]) {
					[_delegate refreshDidTriggerRefresh:self];
				}
				
				[self setState:RefreshLoading];
				[UIView beginAnimations:nil context:NULL];
				[UIView setAnimationDuration:0.2];
				scrollView.contentInset = UIEdgeInsetsMake(70.0f, 0.0f, 0.0f, 0.0f);
				[UIView commitAnimations];
				
			}
			break;
		case RefreshViewBottom:
			if (scrollView.contentOffset.y >= scrollView.contentSize.height + OffSet && !_loading) {
				
				if ([_delegate respondsToSelector:@selector(refreshDidTriggerRefresh:)]) {
					[_delegate refreshDidTriggerRefresh:self];
				}
				
				[self setState:RefreshLoading];
				[UIView beginAnimations:nil context:NULL];
				[UIView setAnimationDuration:0.2];
				scrollView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, -70.0f, 0.0f);
				[UIView commitAnimations];
				
			}
			break;
		case RefreshViewLeft:
			if (scrollView.contentOffset.x <= - OffSet && !_loading) {
				
				if ([_delegate respondsToSelector:@selector(refreshDidTriggerRefresh:)]) {
					[_delegate refreshDidTriggerRefresh:self];
				}
				
				[self setState:RefreshLoading];
				[UIView beginAnimations:nil context:NULL];
				[UIView setAnimationDuration:0.2];
				scrollView.contentInset = UIEdgeInsetsMake(0.0f, 70.0f, 0.0f, 0.0f);
				[UIView commitAnimations];
				
			}
			break;
		case RefreshViewRight:
			if (scrollView.contentOffset.x >= scrollView.contentSize.width - (WIDTH_PAGE + (320.f - WIDTH_PAGE) / 2.f) + OffSet && !_loading) {
				
				if ([_delegate respondsToSelector:@selector(refreshDidTriggerRefresh:)]) {
					[_delegate refreshDidTriggerRefresh:self];
				}
				
				[self setState:RefreshLoading];
				[UIView beginAnimations:nil context:NULL];
				[UIView setAnimationDuration:0.2];
				scrollView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, -70.0f);
				[UIView commitAnimations];
				
			}
			break;
	}
}

- (void)refreshScrollViewDataSourceDidFinishedLoading:(UIScrollView *)scrollView {
	[UIView beginAnimations:nil context:NULL];
	[UIView setAnimationDuration:.3];
	[scrollView setContentInset:UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f)];
	[UIView commitAnimations];
	
	[self setState:RefreshNormal];
}

@end
